import abc
from utils import log_info, log_exception, log_error, log_debug
import threading


class BaseImporter(metaclass=abc.ABCMeta):
    """导入器抽象基类"""

    def __init__(self):
        self.stats = {
            'single_choice': 0,  # 单选题总数
            'multiple_choice': 0,  # 多选题总数
            'has_image': 0,  # 含图片的题目总数
            'single_choice_type_a': 0,  # A类单选题
            'single_choice_type_b': 0,  # B类单选题
            'single_choice_type_c': 0,  # C类单选题
            'multiple_choice_type_a': 0,  # A类多选题
            'multiple_choice_type_b': 0,  # B类多选题
            'multiple_choice_type_c': 0,  # C类多选题
            'image_question_type_a': 0,  # A类含图片题目
            'image_question_type_b': 0,  # B类含图片题目
            'image_question_type_c': 0,  # C类含图片题目
            'elapsed_time': 0  # 导入耗时
        }

    @abc.abstractmethod
    def read_file(self, file_path, progress_var=None, progress_label=None, import_dialog=None):
        """读取文件并解析为题目数据"""
        pass

    def import_to_database(self, questions, progress_var=None, progress_label=None, import_dialog=None):
        """将题目数据导入数据库"""
        try:
            log_debug(f"开始导入数据到数据库")
            
            # 检查questions是否为元组类型（错误返回值）
            if isinstance(questions, tuple) and len(questions) >= 2 and isinstance(questions[0], bool):
                return questions  # 如果是错误返回值，直接返回
            
            # 确保questions是可迭代的列表类型
            if questions is None or not hasattr(questions, '__iter__') or isinstance(questions, (str, dict)):
                questions = []
            
            total = len(questions)
            if total == 0:
                log_error("没有题目数据可导入")
                return False, "题库文件为空", 0, {}

            # 延迟导入 ImportService 以避免循环依赖
            from services import ImportService
            # 初始化导入服务
            import_service = ImportService()

            # 更新进度
            if progress_label and import_dialog:
                progress_label.config(text="正在重置数据库...")
                import_dialog.update_idletasks()

            # 过滤无效题目并收集统计信息
            valid_questions = []
            for q in questions:
                # 检查必要字段
                required_fields = ['Q', 'A', 'B', 'C', 'D', 'T', 'F', 'type']
                if all(key in q for key in required_fields):
                    # 处理空值
                    for key in q:
                        if q[key] is None:
                            q[key] = ''
                    # 收集统计信息
                    self._collect_statistics(q)
                    valid_questions.append(q)

            valid_count = len(valid_questions)
            if valid_count == 0:
                log_error("没有有效的题目数据可导入")
                return False, "没有有效的题目数据可导入", 0, 0, {}

            # 更新进度
            if progress_var and progress_label and import_dialog:
                progress_var.set(30)
                progress_label.config(text="正在批量插入题目...")
                import_dialog.update_idletasks()

            # 导入题目
            success, message, imported_count, _ = import_service.import_questions(valid_questions)

            # 更新进度
            if progress_var and progress_label and import_dialog:
                progress_var.set(100)
                progress_label.config(text="导入完成")
                import_dialog.update_idletasks()

            if success:
                log_debug(f"题库导入完成，成功导入{imported_count}/{valid_count}道题目")
                return True, message, imported_count, valid_count, self.stats
            else:
                log_error(f"导入失败: {message}")
                return False, message, 0, 0, {}

        except Exception as e:
            log_exception(f"导入数据库时发生异常: {str(e)}")
            return False, str(e), 0, 0, {}

    def _collect_statistics(self, question):
        """收集题目统计信息"""
        # 题目类型和分类的交叉统计
        question_type = int(question.get('type', 0))
        is_single_choice = question_type == 1
        is_multiple_choice = question_type == 2
        has_image = question.get('F') and question.get('F') != ''
        is_type_a = int(float(question.get('LA', 0) or 0)) == 1
        is_type_b = int(float(question.get('LB', 0) or 0)) == 1
        is_type_c = int(float(question.get('LC', 0) or 0)) == 1

        # 按题型和分类统计
        if is_single_choice:
            self.stats['single_choice'] += 1
            if is_type_a:
                self.stats['single_choice_type_a'] += 1
            if is_type_b:
                self.stats['single_choice_type_b'] += 1
            if is_type_c:
                self.stats['single_choice_type_c'] += 1
        elif is_multiple_choice:
            self.stats['multiple_choice'] += 1
            if is_type_a:
                self.stats['multiple_choice_type_a'] += 1
            if is_type_b:
                self.stats['multiple_choice_type_b'] += 1
            if is_type_c:
                self.stats['multiple_choice_type_c'] += 1

        # 统计含图片题目
        if has_image:
            self.stats['has_image'] += 1
            if is_type_a:
                self.stats['image_question_type_a'] += 1
            if is_type_b:
                self.stats['image_question_type_b'] += 1
            if is_type_c:
                self.stats['image_question_type_c'] += 1

    def process_data(self, file_path, progress_var=None, progress_label=None, import_dialog=None, async_mode=True):
        """处理数据并导入数据库的通用方法

        Args:
            file_path: 文件路径
            progress_var: 进度条变量
            progress_label: 进度标签
            import_dialog: 导入对话框
            async_mode: 是否异步执行，默认为True

        Returns:
            (success, message, imported_count, stats)四元组
        """
        import queue
        import time

        def import_thread_func(result_queue):
            """在线程中执行导入操作"""
            try:
                start_time = time.time()
                questions = self.read_file(file_path, progress_var, progress_label, import_dialog)
                # 检查questions是否为元组类型（错误返回值）
                if isinstance(questions, tuple) and len(questions) >= 2 and isinstance(questions[0], bool):
                    result_queue.put(questions)
                    return
                if not questions:
                    result_queue.put((False, "读取文件失败或文件为空", 0, {}))
                    return
                result = self.import_to_database(questions, progress_var, progress_label, import_dialog)
                # 添加耗时统计
                if result[0]:  # 如果导入成功
                    elapsed_time = time.time() - start_time
                    self.stats['elapsed_time'] = elapsed_time
                result_queue.put(result)
            except Exception as e:
                log_exception(f"导入线程发生异常: {str(e)}")
                result_queue.put((False, str(e), 0, 0, {}))

        if async_mode and import_dialog:
            # 异步模式
            result_queue = queue.Queue()
            thread = threading.Thread(target=import_thread_func, args=(result_queue,), daemon=True)
            thread.start()

            # 等待线程完成，同时处理UI事件
            while thread.is_alive():
                import_dialog.update()  # 处理UI事件
                time.sleep(0.05)  # 短暂休眠避免CPU占用过高

            # 获取结果
            try:
                return result_queue.get_nowait()
            except queue.Empty:
                return False, "导入结果为空", 0, {}
        else:
            # 同步模式
            start_time = time.time()
            questions = self.read_file(file_path, progress_var, progress_label, import_dialog)
            # 检查questions是否为元组类型（错误返回值）
            if isinstance(questions, tuple) and len(questions) >= 2 and isinstance(questions[0], bool):
                return questions
            if not questions:
                return False, "读取文件失败或文件为空", 0, {}
            result = self.import_to_database(questions, progress_var, progress_label, import_dialog)
            # 添加耗时统计
            if result[0]:  # 如果导入成功
                elapsed_time = time.time() - start_time
                self.stats['elapsed_time'] = elapsed_time
            return result